Eddie's Lessons, version 12

Adding Font Size Option

level: any

by Alyce Watson [http://alycesrestaurant.com/]

Home

LB Browser

4.03 Review

LED Display

Sprite Byte Masks

API Corner

Ini Files

Registration Keys

Eddie Fonts

Dragging a Popup

Random Audio Player

Eddie

Submissions

Index


What is Eddie?

Eddie is a new code editor written in Liberty BASIC, for Liberty BASIC. Eddie can be customized and extended to meet the needs of the individual programmer. The newest version is available here: Eddie!



Setting the Font Size

Eddie adds a feature to the Options Menu for this version. It allows the user to set the height of the font. The new options menu looks like this:

Menu        #1, "&Options", "&Syntax Color On/Off",[syntaxColor],"&Line Numbers On/Off",[lineNumbers],|,_
            "Set &Default Color", [doDefaultColor],"Set &Background Color", [doBackgroundColor],|,_
            "Set &Keyword Color", [doKeywordColor],"Set &Comment Color", [doCommentColor],"Set &Quote Color",_
            [doQuoteColor],"Set &Operator Color", [doOperatorColor], |, "&Font Size", [changeFont]

A simple call to CodeAChrome changes the font size. The value for the "nFont" argument sets the height of the font. There is no way to change the font face. Since CodeAChrome is intended for code editing, the Courier New monospaced font is used by default.

    calldll #r, "SetFontSize",_
    nFont as long,_    'desired height of font
    re as void

Eddie stores the size of the font in the variable FontSize$, which is a string variable, so the VAL() function is used to convert the value into a number for use in the API call. We prompt the user for a font size, and if the user selects a size smaller than 8, we set the size to 8. If he selects a size greater than 24, we set the size to 24. (This could also be done using MIN() and MAX() -- why not try converting it yourself?)

[changeFont]
    nFont = val(FontSize$)
    prompt "Size for font?";nFont
    if nFont<8 then nFont = 8
    if nFont>24 then nFont = 24
    FontSize$ = str$(nFont)
    call SetFontSize FontSize$
    wait

Eddie calls the Sub to SetFontSize, which looks like this. The sub accepts a string variable and converts it to a numeric value for the API call.

Sub SetFontSize fSize$    
    nFont = val(fSize$)
    calldll #r, "SetFontSize", nFont as long, re as void
    calldll #r, "DoSetFocus", re as void
    end sub

Changing the Ini File to API Version

This issue contains an article on API ini files. Please read that article to understand the changes in Eddie's ini file routines. Eddie will call on these two wrapper routines to write to and read from the ini file that saves user preferences.

Sub WriteIniFile lpAppName$, lpKeyName$, lpString$, lpFileName$
    CallDLL #kernel32, "WritePrivateProfileStringA", _
        lpAppName$ As ptr, _    'section name 
        lpKeyName$ As ptr, _    'key name   
        lpString$ As ptr, _     'key value
        lpFileName$ As ptr, _   'ini filename
        result As boolean       'nonzero = success
    end sub

Function GetIniFile$(lpAppName$, lpKeyName$,lpDefault$,lpFileName$)
    nSize=100
    lpReturnedString$=Space$(nSize)+Chr$(0)
    CallDLL #kernel32, "GetPrivateProfileStringA", _
        lpAppName$ As ptr, _'section name 
        lpKeyName$ As ptr, _'key name 
        lpDefault$ As ptr, _'default string returned if there is no entry
        lpReturnedString$ As ptr, _ 'destination buffer
        nSize As long, _            'size of destination buffer
        lpFileName$ As ptr, _       'ini filename
        result As ulong     'number of characters copied to buffer

    GetIniFile$=Left$(lpReturnedString$,result)
    end function

The new routines that call on these API functions are below. The routines are more streamlined, since the API ini file allows us to set a default value if the key has no set value. We've also added to the ini file to save and retrieve the coordinates and size of the window when the user last ran Eddie.

[readIniFile]
    LibertyExe$ = GetIniFile$("Eddie", "LibertyExe","none","eddie12.ini")
    Freeform$ = GetIniFile$("Eddie", "Freeform","none","eddie12.ini")
    Runtime$ = GetIniFile$("Eddie", "Runtime","none","eddie12.ini")
    Help$ = GetIniFile$("Eddie", "Help","none","eddie12.ini")
    TextColor$ = GetIniFile$("Eddie", "TextColor",TextColor$,"eddie12.ini")
    BackColor$ = GetIniFile$("Eddie", "BackColor",BackColor$,"eddie12.ini")
    KeywordColor$ = GetIniFile$("Eddie", "KeywordColor",KeywordColor$,"eddie12.ini")
    QuoteColor$ = GetIniFile$("Eddie", "QuoteColor",QuoteColor$,"eddie12.ini")
    CommentColor$ = GetIniFile$("Eddie", "CommentColor",CommentColor$,"eddie12.ini")
    OperatorColor$ = GetIniFile$("Eddie", "OperatorColor",OperatorColor$,"eddie12.ini")
    FontSize$ = GetIniFile$("Eddie", "FontSize",FontSize$,"eddie12.ini")
    'window X,Y,WIDTH,HEIGHT at user's last values
    ULX = VAL(GetIniFile$("Eddie", "ULX","10","eddie12.ini"))
    ULY = VAL(GetIniFile$("Eddie", "ULY","10","eddie12.ini"))
    WIDTH = VAL(GetIniFile$("Eddie", "WIDTH","400","eddie12.ini"))
    HEIGHT = VAL(GetIniFile$("Eddie", "HEIGHT","300","eddie12.ini"))

    if LibertyExe$ = "none" then
        notice "To use Eddie successfully, you must set the path to Liberty.exe, Freeform, the runtime engine and the helpfile."
        gosub [GetLibertyPath]
        gosub [GetFreeformPath]
        gosub [GetRuntimePath]
        gosub [GetHelpPath]
    end if
    RETURN

[writeIniFile]
    call WriteIniFile "Eddie", "LibertyExe", LibertyExe$,"eddie12.ini"
    call WriteIniFile "Eddie", "Freeform", Freeform$,"eddie12.ini"
    call WriteIniFile "Eddie", "Runtime", Runtime$,"eddie12.ini"
    call WriteIniFile "Eddie", "Help", Help$,"eddie12.ini"
    call WriteIniFile "Eddie", "TextColor", TextColor$,"eddie12.ini"
    call WriteIniFile "Eddie", "BackColor", BackColor$,"eddie12.ini"
    call WriteIniFile "Eddie", "KeywordColor", KeywordColor$,"eddie12.ini"
    call WriteIniFile "Eddie", "QuoteColor", QuoteColor$,"eddie12.ini"
    call WriteIniFile "Eddie", "CommentColor", CommentColor$,"eddie12.ini"
    call WriteIniFile "Eddie", "OperatorColor", OperatorColor$,"eddie12.ini"
    call WriteIniFile "Eddie", "FontSize", FontSize$,"eddie12.ini"
    RETURN

Checking for a Minimized Window

We're adding a new feature to Eddie this month. We'll save the size and location of Eddie when the program ends, so that we can automatically open Eddie at those coordinates next time. Before checking for the coordinates, we need to make sure that the window hasn't been minimized to the task bar. It's not a good idea to start a program in the minimized mode. The code to check for a minimized window is explained in the article on API ini files in this issue.

Eddie's code to check for a minimized window is contained in the "quit" routine and it is as follows:

    calldll #user32, "IsIconic",_
    hMain as ulong,_   'handle of window
    result as boolean  'returns true if window is minimized

Retrieving Window Coorinates

In the "quit" routine, if the window is not minimized, we want to retrieve the window coordinates. This API function to GetWindowRect is explained in the article on API ini files in this issue. Here is Eddie's code to retrieve those coordinates and write them to the ini file.

[quit]
    calldll #user32, "IsIconic",_
    hMain as ulong,_   'handle of window
    result as boolean  'returns true if window is minimized
    if not(result) then
        struct Rect, x1 As Long, y1 As Long, x2 As Long, y2 As Long
        CallDLL #user32, "GetWindowRect",hMain as uLong, Rect As struct, result As Long
        ulx = Rect.x1.struct : uly = Rect.y1.struct
        width = Rect.x2.struct - ulx
        height = Rect.y2.struct - uly
       'write location and size of window to ini file   
        call WriteIniFile "Eddie", "ULX", str$(ulx), "eddie12.ini"
        call WriteIniFile "Eddie", "ULY", str$(uly), "eddie12.ini"
        call WriteIniFile "Eddie", "WIDTH", str$(width), "eddie12.ini"
        call WriteIniFile "Eddie", "HEIGHT", str$(height), "eddie12.ini"
    end if    

    gosub [writeIniFile]
    calldll #r, "DestroyCodeAChrome", ret as void
    close #r : close #1 : END

Opening the Window at the User's Last Position

The API ini file allows us to set default values for the keys, so we can set defaults for UpperLeftX, UpperLeftY, WindowWidth and WindowHeight. If Eddie is being run for the first time, those defaults will be used. If the user has run Eddie before, the window will open at the last used coordinates and dimensions.

Before opening the window, we invoke a subroutine to read the ini file, like this:

    gosub [readIniFile]

While reading the ini file, the UpperLeftX, UpperLeftY, WindowWidth and WindowHeight are set. Here's that part of the code:

    'window X,Y,WIDTH,HEIGHT at user's last values
    ULX = VAL(GetIniFile$("Eddie", "ULX","10","eddie12.ini"))
    ULY = VAL(GetIniFile$("Eddie", "ULY","10","eddie12.ini"))
    WIDTH = VAL(GetIniFile$("Eddie", "WIDTH","400","eddie12.ini"))
    HEIGHT = VAL(GetIniFile$("Eddie", "HEIGHT","300","eddie12.ini"))

After reading the ini file and opening the window, we use those values to set the location and size of the window. Since we use the MoveWindow API call to invoke the resizehandler after opening the window, we'll use those values in the call:

    'activate resizehandler
    calldll #user32, "MoveWindow",_
    hMain as ulong, _       'window handle
    ULX as long,_    'x location of window
    ULY as long,_    'y location of window
    WIDTH as long,_  'desired width of window
    HEIGHT as long,_ 'desired height of window
    1 as boolean, ret as long


Home

LB Browser

4.03 Review

LED Display

Sprite Byte Masks

API Corner

Ini Files

Registration Keys

Eddie Fonts

Dragging a Popup

Random Audio Player

Eddie

Submissions

Index